﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows;
namespace vmlModel.Entities
{
    public class vmlPathShapeBase : vmlShapeBase
    {
        public string Path { get { return (vmlObjElement.Attribute("path") != null) ? vmlObjElement.Attribute("path").Value : ""; } }
        public List<vmlSubPath> SubPaths { get; set; }
        public List<vmlFormula> Formulas { get; set; }
        public Size coordsize
        {
            get
            {
                if (vmlObjElement.Attribute("coordsize") != null)
                {
                    Size cs = new Size();
                    cs.Width =  vmlObjElement.Attribute("coordsize").Value.Split(',')[0].ToDouple();
                    cs.Height = vmlObjElement.Attribute("coordsize").Value.Split(',')[1].ToDouple();
                    return cs;
                }
                return new Size(1, 1);
            }
        }
        public List<double> Adjustments
        {
            get
            {
                var adjs = new List<double>();
                if (vmlObjElement.Attribute("adj") != null)
                {
                    foreach (var item in vmlObjElement.Attribute("adj").Value.Split(','))
                    {
                        adjs.Add(item.ToDouple());  
                    }
                }
                return adjs;
            }
        }
        public double GetAdjustment(string adjID)
        {
            if (string.IsNullOrEmpty(adjID))

	            {
		            return 0; 
	            }
            adjID = adjID.Replace("#","");
            return Adjustments[int.Parse(adjID)];
            
        }
        public double GetFormula(string fID)
        {
            if (string.IsNullOrEmpty(fID))
            {
                return 0;
            }
            fID = fID.Replace("@", "");
            return Formulas[int.Parse(fID)].Result;

        }
        public double FormulaCalculateString(string paramter)
        {
            if (paramter.Trim().StartsWith("#"))
            {
                paramter = paramter.Replace("#", "");
                return GetAdjustment(paramter);
            }
            if (paramter.Trim().StartsWith("@"))
            {
                paramter = paramter.Replace("@", "");
                return  GetFormula(paramter);
            }
            if (paramter.Trim().ToLower() == "height")
            {
                return this.coordsize.Height ;
            }
            if (paramter.Trim().ToLower() == "width")
            {
                return this.coordsize.Width;
            }
            
            return double.Parse(paramter);
        }
        public vmlPathShapeBase()
        {

        }
        public vmlPathShapeBase(XElement _vmlObjElement)
            : base(_vmlObjElement)
        {
            Formulas = new List<vmlFormula>();
            FillMe();
           if(!string.IsNullOrEmpty(Path)) AnalyzePath();
        }

    

        private void FillMe()
        {
            // get the PathShape Subelements
            foreach (XElement element in from elemnt in vmlObjElement.Elements()
                                         select elemnt)
            {
                switch (element.Name.LocalName.ToLower())
                {
                    case "formulas":
                        foreach (XElement formula in from f in element.Elements()
                                                     select f)
                        {
                            switch (formula.Name.LocalName.ToLower())
                            {
                                case "f":
                                    Formulas.Add(new vmlFormula(this, formula));
                                    break;
                                default:
                                    break;
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        private void AnalyzePath()
        {
          string path =  RefinePath();
          SubPaths = new List<vmlSubPath>();

            
            // get the subpaths list
          foreach (var item in path.Trim().Split('e'))
          {
              if (item != "" && item != "&")
              {
                  SubPaths.Add(new vmlSubPath( this ,item.Trim()));
              } 
          } 


        }
 
        private string  RefinePath()
        { 
            var commandKeys = new string[] { "nf", "ns", "ae", "al", "at", "ar", "wa", "wr", "qx", "qy", "qb", "m", "l", "c", "x", "e", "t", "r", "v" };
            // Refine the Path
            string path = Path.Replace("@", ",@");
            path = path.Replace(",,", ",0,");
            /////////////////
            foreach (var commandKey in commandKeys)
            {
                path = path.Replace(commandKey + ",@", commandKey + "@");
                path = path.Replace(commandKey + ",", commandKey + "0,");
                path = path.Replace("," + commandKey, ",0" + commandKey);
                path = path.Replace(commandKey, " " + commandKey);
                path = path.Replace(commandKey,  commandKey + "&"); //Command identifier
            }
            // fix the overlapped commands
            path = path.Replace("q x", "qx");
            path = path.Replace("a r", "ar");
            path = path.Replace("a e", "ae");
            path = path.Replace("a t", "at");
            path = path.Replace("w r", "wr");

            //////End of  Refining the Path

            ///////////////
            return path;
        }

   

    }
}
